#include "./EventLoopThread.h"
#include "./EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb,
                                 const std::string &name)
    : thread_(std::bind(&EventLoopThread::threadFunc, this), name),
      callback_(cb),
      loop_(nullptr),
      isQuit_(false),
      mtx_(), // 也可以不用
      cond_()
{
}

// 给线程注册的回调
void EventLoopThread::threadFunc()
{
    EventLoop loop{};

    if (this->callback_)
    {
        this->callback_(&loop);
    }

    {
        std::unique_lock<std::mutex> lock(this->mtx_);

        this->loop_ = &loop;
        this->cond_.notify_one();
    }

    loop.start(); // EventLoop::start() -> Poller::poll()

    // poller不玩了解阻塞返回
    std::unique_lock<std::mutex> lock(this->mtx_);

    this->loop_ = nullptr;
}

EventLoopThread::~EventLoopThread()
{
    this->isQuit_ = true;

    if (this->loop_ != nullptr)
    {
        this->loop_->quit();
        this->thread_.join();
    }
}

EventLoop *EventLoopThread::startLoop()
{
    this->thread_.start(); // 启动底层的新线程

    // 上面的子线程会执行EventLoopThread::threadFunc()创建loop
    // 然后条件变量通知当前线程
    // 当前线程this->loop_拿到子线程的loop
    EventLoop *loop{nullptr};
    {
        std::unique_lock<std::mutex> lock(this->mtx_);

        // 避免惊群效应的虚假唤醒 × cpp文档notify_one()没有
        // while (this->loop_ == nullptr)
        // {
        //     this->cond_.wait(lock);
        // }
        // this->loop_ != nullptr 为true解阻塞
        cond_.wait(lock, [this]()
                   { return this->loop_ != nullptr; });

        loop = this->loop_;
    }

    return loop;
}